#include "RandomSolver.hpp"
#include <cstdlib>
#include <cmath>

/*
 * 	Pour le veritable algo genetique et le cross :
 * 		on prend une tournee pourrie d'une sol A et une tournee bien d'une sol B
 * 		il faut qu'elles aient au moins 1 client en commun
 * 		on extrait la liste des clients
 * 		on balance tout dans le merger
 * 		=> on obtiendra alors plusieurs tournees, et avec du bol deux, et beaucoup de bol une seule
 * 
 * 	Pour ameliorer le merger, penser eventuellement a creer une tri-subsol
 * 	au lieu d'une bi-subsol. Et alterner dans le merger entre tri et bi subsol.
 * 	// il faut pour cela essayer de coder un or-opt entre trois tournees
 * 	// et un 2-opt entre trois tournees
 */

void	RandomSolver::execute() EXC_THROWER()
{
	EXC_RETHROW_BEGIN()
	{
		unsigned	iteration = 0;
		unsigned 	amelioration_iteration = 0;
		
		SolutionEval	soleval;
		SolutionEval	bestsoleval;
		TourneeEvalResult	teval;
		
		Solution sol(soVRPTW);
		Solution bestsol(soVRPTW);
		
		sol.complete();
		bestsol = sol;
		
		sol.eval(&soleval);
		bestsoleval = soleval;
		
		for (;;iteration++)
		{
			unsigned	tournee1;
			unsigned	tournee2;
			
			//sol = bestsol;
			
			do
			{
				tournee1 = sol.getFilledRandomTournee();
				if (soleval.seNTournees == soVRPTW.size())
				{
					tournee2 = sol.getFilledRandomTournee();
				}
				else if ((rand() % ((soVRPTW.size() - soleval.seNTournees) + 1)) == 0)
				{
					tournee2 = sol.getEmptyRandomTournee();
				}
				else
					tournee2 = sol.getFilledRandomTournee();
					
			}	while (tournee1 == tournee2);
			
			localVND(sol[tournee1], sol[tournee2], 5);
			sol.validateTournee(tournee1);
			sol.validateTournee(tournee2);
			
			//sol.shuffle();
			sol.reorganize();
			//sol.reorganizeBySizeCouples();
			sol.eval(&soleval);
			
			if (soleval < bestsoleval)
			{
				bestsol = sol;
				bestsoleval = soleval;
					//std::cout << bestsol.toString() << std::endl;
				std::cout << bestsoleval.toString() << std::endl;
				amelioration_iteration = iteration;
			}
			else
			{
				sol = bestsol;
				/*unsigned	tournee;
				
				tournee = sol.getEmptyRandomTournee();
				
				sol[tournee].addRandomRDepot();
				sol.validateTournee(tournee);*/
				
				
			}
		}
	}
	EXC_RETHROW_END()
}
